<?php

namespace Library\Abstracts;

use Closure;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Exception;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\ORMSetup;

abstract class AbstractDbal
{
    /**
     * @var Connection|null
     */
    protected ?Connection $conn = null;
    protected ?EntityManager $manager = null;

    /**
     * @param array $database
     * @param Configuration|null $config
     */
    public function __construct(array $database,?Configuration $config = null)
    {
        $paths = app()->getConfig("orm-entity-paths");
        $isDevMode= app()->getConfig("debug");
        $dbParams = app()->getConfig("database");
        $dbParams = array_merge($dbParams,$database);
        $config = ORMSetup::createAttributeMetadataConfiguration($paths, $isDevMode);
        $this->conn = DriverManager::getConnection($dbParams, $config);
        $this->manager = new EntityManager($this->conn, $config);
    }



    /**
     * @return void
     * @throws Exception
     */
    public function query(string $sql): void
    {
        $this->conn->executeQuery($sql);
    }

    /**
     * 事物操作
     * @param Closure $closure
     * @return void
     * @throws Exception
     */
    public function transaction(Closure $closure):void
    {
        $this->conn->beginTransaction();
        try {
            $closure($this);
            $this->conn->commit();
        }catch (Exception $e){
            $this->conn->rollBack();
        }
    }

    public function __clone(): void
    {
        // TODO: Implement __clone() method.
    }

    public function __destruct()
    {
        $this->conn->close();
    }
}